//
//  SecondDegSolver.m
//  SecondDeg
//
//  Created by Stéphane Delval on 09/01/10.
//  Copyright 2010 BiWiLabs. All rights reserved.
//
// @author : Stephane Delval
// @version : 0.1.0
// @comment : implementation of the equation of second degre.

#import "SecondDegSolver.h"


@implementation SecondDegSolver

// method definitions for calculation & output of calculation results (error/success/delta neg)

- (double) getDelta: (double)Param1 //Term_A
             Term_B: (double)Param2
             Term_C: (double)Param3
{
    // Declaration of the local variable:
    //This declaration is useness. It can be avoid by returning the formula like this
    // return (Param2 * Param2) - (4 * Param1 * Param3 );
    double calculatedDelta;

    // Main calculation code:
    calculatedDelta = (Param2 * Param2) - (4 * Param1 * Param3 );

    return calculatedDelta;
}

- (double) getSolution: (double)firstParameter
                Term_B: (double)secondParameter
                Term_C: (double)thirdParameter
{    
    double deltaValue;
    
    // Calling the calculation of deltaValue:
    deltaValue = [self getDelta: firstParameter
                         Term_B: secondParameter
                         Term_C: thirdParameter];
    
    if ( deltaValue < 0 )
    {
        result_msg = MSG_DELTA_NEG;
    }
    else
    {
        if ( firstParameter != 0 )
        {
            firstSolution  = (-secondParameter + sqrt(deltaValue)) / (2 * firstParameter);
            secondSolution = (-secondParameter - sqrt(deltaValue)) / (2 * firstParameter);
            result_msg     = MSG_SUCCESS;
        }
        else
        {
            if ( secondParameter != 0 )
            {
                // The firstParameter is zero. The problem degenerates into solving
                // a first degree equation.

                firstSolution  = -thirdParameter / secondParameter;
                secondSolution = -thirdParameter / secondParameter;
                result_msg     = MSG_SUCCESS;
            }
            else
            {
                // do nothing. firstParameter and secondParameter are zero
                // there is no equation anymore. result_msg is MSG_ERROR.
            }
        }
    }
    
    return result_msg;
}

// --------------------------------------------------------------------------
// method for only keeping a certain number of digits after the decimal point 
// *** WARNING *** there is no overflow protection!
// It may not be the most efficient way to obtain the result, but it is all
// I found at the moment.
// --------------------------------------------------------------------------
- (double) getTruncatedValueOf: (double)myValueToRound
                          with: (int)myNumberOfDigitsAfterDecimal
{
    // Declaration of the local variable:
    double calculatedValue;

    // Main calculation code:
    calculatedValue = myValueToRound;

    if (    ( myNumberOfDigitsAfterDecimal > 0 )
         && ( myValueToRound != 0              ))
    {
        for (int i = 0; i < myNumberOfDigitsAfterDecimal; i++)
        {
            calculatedValue = calculatedValue * 10;
        }

        calculatedValue = round(calculatedValue);

        for (int i = 0; i < myNumberOfDigitsAfterDecimal; i++)
        {
            calculatedValue = calculatedValue / 10;
        }
    }

    return (calculatedValue);
}

// methods for displaying the solutions in case of success (getters)
- (double) getFirstSolution: (int)DigitNumbersAfterDecimal;
{
    return ( [self getTruncatedValueOf: firstSolution
                                  with: DigitNumbersAfterDecimal] );
}
- (double) getSecondSolution: (int)DigitNumbersAfterDecimal;
{
    return ( [self getTruncatedValueOf: secondSolution
                                  with: DigitNumbersAfterDecimal] );
}

// initialization
- (id) init
{
    //initialize the superclass and assign it to self
    if ( self == [super init])
    {
        //now that you know self has been inited,
        //you can work with its instance variables
        result_msg     = MSG_ERROR; //default value
        firstSolution  = 0;
        secondSolution = 0;
    }
    return self;
}


@end